package org.example.nettydemo.netty.redis;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.redis.ArrayRedisMessage;
import io.netty.handler.codec.redis.FullBulkStringRedisMessage;
import io.netty.handler.codec.redis.RedisMessage;

/**
 * @author liujing
 * 处理 Redis 服务器的响应
 */

class RedisClientHandler extends SimpleChannelInboundHandler<RedisMessage> {
    private final String password;
    private Channel channel;

    public RedisClientHandler(String password) {
        this.password = password;
    }

    /**
     * 连接建立后自动执行 Redis 认证和 PING
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        this.channel = ctx.channel();
        authenticate();
    }

    /**
     * 发送认证命令（AUTH）并执行 PING
     */
    private void authenticate() {
        if (password != null && !password.isEmpty()) {
            // 发送 AUTH your_password
            sendCommand("AUTH", password);
        }
        // 发送 PING 命令
        sendCommand("PING");
        // 发送 SET 命令
        sendCommand("SET", "netty_key", "Hello, Redis!");
    }

    /**
     * 发送 Redis 命令
     */
    private void sendCommand(String... args) {
        RedisMessage request = createRedisMessage(args);
        channel.writeAndFlush(request);
    }

    /**
     * 将 Java 字符串数组转换为 RedisMessage（用于发送 Redis 命令）
     */
    private RedisMessage createRedisMessage(String... args) {
        RedisMessage[] redisMessages = new RedisMessage[args.length];
        for (int i = 0; i < args.length; i++) {
            redisMessages[i] = new FullBulkStringRedisMessage(io.netty.buffer.Unpooled.wrappedBuffer(args[i].getBytes()));
        }
        return new ArrayRedisMessage(java.util.Arrays.asList(redisMessages));
    }

    /**
     * 处理 Redis 返回的数据
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RedisMessage msg) {
        System.out.println("Received response: " + msg);
    }

    /**
     * 处理异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}